#!/bin/sh
#
# IRC - Internet Relay Chat, tools/transition
# Copyright (C) 2001 Kevin L. Mitchell <klmitch@mit.edu>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# $Id: transition 1969 2007-06-30 10:09:22Z sirvulcan $

# Better than having evals all over the place
setvar () {
    eval $1=\$2
}
getvar () {
    eval echo \$$1
}

# Set up an echo that doesn't newline-terminate
if test x`echo -n` = x-n; then
    echo_n () {
	echo "$@"'\c'
    }
else
    echo_n () {
	echo -n "$@"
    }
fi

# Debugging notices, enabled only if $DEBUG has something in it
if test x"$DEBUG" = x; then
    deb () {
	:
    }
    deb_n () {
	:
    }
else
    deb () {
	echo "$@"
    }
    deb_n () {
	echo_n "$@"
    }
fi

# Get base directory; first step, how were we called?
case $0 in
*/*)
    basedir=`echo $0 | sed -e 's@/[^/]*@@g'`
    ;;

*)
    basedir=`pwd`
    ;;
esac

# Now locate the ircd subdirectory
if test -d $basedir/ircd; then
    :
elif test -d $basedir/../ircd; then
    basedir=$basedir/..
elif test -d ./ircd; then
    basedir=`pwd`
else
    echo "Cannot find base ircd directory!" >&2
    exit 1
fi

# Finally, canonicalize it
cwd=`pwd`
cd $basedir
basedir=`pwd`
cd $cwd

deb "Base directory: $basedir"

# This is where our ./configure-parsable results will go
cache_file=$basedir/config.cache

# Now locate .config and config.cache
config_in=
config_cache_in=

# If the config subdirectory isn't there anymore, don't bother checking there
if test -d $basedir/config; then
    if test -r $basedir/config/.config; then
	config_in=$basedir/config/.config
    fi

    if test -r $basedir/config/config.cache; then
	config_cache_in=$basedir/config/config.cache
    fi
fi

# Last ditch effort...try ../.config
if test x"$config_in" = x; then
    if test -r $basedir/../.config; then
	config_in=$basedir/../.config
    else
	echo "Cannot find original .config file!" >&2
	exit 2
    fi
fi

# Last ditch effort...try ../.config.cache
if test x"$config_cache_in" = x; then
    if test -r $basedir/../.config.cache; then
	config_cache_in=$basedir/../.config.cache
    else
	echo "Cannot find original config.cache file!" >&2
	exit 3
    fi
fi

# Now load the two data files
echo "Loading old config.cache file $config_cache_in"
. $config_cache_in
echo "Loading old .config file $config_in"
. $config_in

# Now we have to track down the defaults so we will know what to generate
# F-lines for
if test ! -r $basedir/ircd/ircd_features.c; then
    echo "Cannot find default features!" >&2
    exit 4
fi

echo_n "Loading feature default values; please be patient... "
deb ""
features=
exec 4<$basedir/ircd/ircd_features.c
while read line <&4; do
    # if a line has '(' but not ')', then we hang them until we find the
    # matching ')'; this is not robust!
    if test x"$hangline" != x; then
	line="$hangline $line"
	hangline=
    fi

    if test x"`echo "$line" | grep '(' 2>/dev/null`" != x -a \
	    x"`echo "$line" | grep ')' 2>/dev/null`" = x; then
	hangline=$line
	continue
    fi

    # Now we process the line we read...
    case $line in
    \#*) # We want to ignore the #define, since it's a false positive
	;;

    F_[NIBS]*) # Found one of the feature define macros
	type=`echo "$line" | sed -e 's/^F_\([NIBS]\).*$/\1/g'`
	arglist=`echo "$line" | sed -e 's/^F_[NIBS](\(.*\)),.*/\1/g' \
		 -e 's/ | /|/g'`

	# Now we must parse the arguments
	tIFS=$IFS
	IFS=,$IFS
	name=
	value=
	argnum=0
	for arg in $arglist; do
	    case $type$argnum in
		[NIBS]0) # First argument is always the name of the feature
		    name=$arg
		    ;;

		I2) # Second argument of F_I() is the numerical value
		    value=$arg
		    ;;

		B2) # Second argument of F_B() is a numerical value
		    # We must convert this numerical value to "y" or "n"
		    if test x"$arg" = x0; then
			value=n
		    else
			value=y
		    fi
		    ;;

		[ST]2) # Second argument of F_S() is a string value; must
		       # take into account unquoted possibilities, though
		    dequote=`echo "$arg" | sed -e 's/^"\(.*\)"$/\1/g'`
		    if test x"$dequote" = x"$arg"; then
			type=T
			value=$arg
		    else
			value=$dequote
		    fi
		    ;;
	    esac

	    # Next time through, we'll be testing the next argument
	    argnum=`expr $argnum + 1`
	done
	IFS=$tIFS

	deb "Loaded feature \"$name\" of type \"$type\"; default: \"$value\""

	# Store the information we extracted
	setvar type_$name $type
	setvar def_$name "$value"

	# Keep a list of features we've checked
	features="$features $name"
	;;
    esac
done
exec 4<&-
echo "done"

echo "Converting some options that are still compile-time"

unet_cv_prefix=`echo $SPATH | sed -e 's@/bin/ircd@@g'`
deb "Installation directory (derived from SPATH)... $unet_cv_prefix"

deb_n "Enable debugging (DEBUGMODE)... "
if test x"$DEBUGMODE" = xy; then
    unet_cv_enable_debug=yes
else
    unet_cv_enable_debug=no
fi
deb "$unet_cv_enable_debug"

deb_n "Enable assertion checking (CONFIG_NDEBUG)... "
if test x"$CONFIG_NDEBUG" = xy; then
    unet_cv_enable_asserts=yes
else
    unet_cv_enable_asserts=no
fi
deb "$unet_cv_enable_asserts"

deb_n "Force inlining of some critical functions (FORCEINLINE)... "
if test x"$FORCEINLINE" = xy; then
    unet_cv_enable_inlines=yes
else
    unet_cv_enable_inlines=no
fi
deb "$unet_cv_enable_inlines"

unet_cv_with_symlink=$SYMLINK
deb "Symlink name (SYMLINK)... $unet_cv_with_symlink"

unet_cv_with_mode=$IRCDMODE
deb "Binary permissions (IRCDMODE)... $unet_cv_with_mode"

unet_cv_with_owner=$IRCDOWN
deb "Binary owner (IRCDOWN)... $unet_cv_with_owner"

unet_cv_with_group=$IRCDGRP
deb "Binary group owner (IRCDGRP)... $unet_cv_with_group"

unet_cv_with_domain=$DOMAINNAME
deb "Local domain name (DOMAINNAME)... $unet_cv_with_domain"

deb_n "Enable CHROOT operation (CHROOTDIR)... "
if test x"$CHROOTDIR" = xy; then
    deb_n "yes, path "
    unet_cv_with_chroot=$DPATH
else
    unet_cv_with_chroot=no
fi
deb "$unet_cv_with_chroot"

unet_cv_with_dpath=$DPATH
deb "Data path (DPATH)... $unet_cv_with_dpath"

unet_cv_with_cpath=$CPATH
deb "Configuration file (CPATH)... $unet_cv_with_cpath"

# LPATH may not be set; if it's not, we'll just ignore it here and let
# ./configure fill it in appropriately
if test x"$LPATH" != x; then
    unet_cv_with_lpath=$LPATH
    deb "Debug log file (LPATH)... $unet_cv_with_lpath"
fi

unet_cv_with_maxcon=$MAXCONNECTIONS
deb "Maximum number of connections (MAXCONNECTIONS)... $unet_cv_with_maxcon"

# Shouldn't run ./configure before the transition script, but we can deal
if test -r "$cache_file"; then
    echo "WARNING: Destroying new config.cache file $cache_file" >&2
    rm $cache_file
fi

# Create the cache file...
echo "Creating new config.cache file $cache_file"
> $cache_file

# This section is copied from a GNU autoconf-generated configure script
###############################################################################
cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs.  It is not useful on other systems.
# If it contains results you don't want to keep, you may remove or edit it.
#
# By default, configure uses ./config.cache as the cache file,
# creating it if it does not exist already.  You can give configure
# the --cache-file=FILE option to use a different cache file; that is
# what configure does when it calls configure scripts in
# subdirectories, so they share the cache.
# Giving --cache-file=/dev/null disables caching, for debugging configure.
# config.status only pays attention to the cache file if you give it the
# --recheck option to rerun configure.
#
EOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
  case `(ac_space=' '; set | grep ac_space) 2>&1` in
  *ac_space=\ *)
    # `set' does not quote correctly, so add quotes (double-quote substitution
    # turns \\\\ into \\, and sed turns \\ into \).
    sed -n \
      -e "s/'/'\\\\''/g" \
      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
    ;;
  *)
    # `set' quotes correctly as required by POSIX, so do not add quotes.
    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
    ;;
  esac >> confcache
if cmp -s $cache_file confcache; then
  :
else
  if test -w $cache_file; then
    echo "updating cache $cache_file"
    cat confcache > $cache_file
  else
    echo "not updating unwritable cache $cache_file"
  fi
fi
rm -f confcache
###############################################################################

# If they ran ./configure before, there'll be a config.status hanging around;
# if so, we can run that to integrate the config.cache we just generated.
if test -x $basedir/config.status; then
    echo "Running $basedir/config.status to update configuration"
    cwd=`pwd`
    cd $basedir
    # Have to run it twice to get the Makefile recreated
    ./config.status --recheck
    ./config.status
    cd $cwd
fi

# Now we need to track down ircd.conf so we can add the F-lines.
echo_n "Locating IRCD configuration file... "
case $unet_cv_with_cpath in
/*) # CPATH is absolute
    conf_file=$unet_cv_with_cpath
    ;;

*) # CPATH is relative to DPATH
    conf_file=$unet_cv_with_dpath/$unet_cv_with_cpath
    ;;
esac
# suppress duplicate '/'
conf_file=`echo "$conf_file" | sed -e 's@//*@/@g'`
echo "$conf_file"

# if we can't find the .conf, use "flines.conf" in the base directory (so
# they'll be easy to find).
if test ! -r $conf_file; then
    fline_conf=yes
    conf_file=$basedir/flines.conf
    if test ! -r $conf_file; then
	> $conf_file
    fi
    echo "WARNING: Unable to read ircd.conf; you will need to add the" >&2
    echo "         F-lines manually.  For your convenience, they will be" >&2
    echo "         placed in $conf_file." >&2
fi

# here's where we take the old .config and compare it to the feature defaults
echo_n "Building feature table... "
for feature in $features; do
    defval=`getvar def_$feature`
    value=`getvar $feature`

    if test x"$value" = x -o x"$value" = x"$defval"; then
	setvar FEAT_$feature $defval
    else
	setvar FEAT_$feature $value
    fi
done

# We won't add an F-line for DOMAINNAME, since (hopefully) the right one is
# already compiled in
FEAT_DOMAINNAME=DOMAINNAME

# Have to make sure we have a RANDOM_SEED to enhance randomness...
FEAT_RANDOM_SEED=$RANDOM_SEED

# This feature changed names to be consistent...
FEAT_OPER_LBADCHAN=$LOCAL_BADCHAN

# DEFAULT_LIST_PARAM is perhaps the most complicated to transition, but
# this'll do the trick...
if test x"$CONFIG_LIST" = xy; then
    FEAT_DEFAULT_LIST_PARAM=$DEFAULT_LIST_PARAM
else
    FEAT_DEFAULT_LIST_PARAM=0
fi

echo "done"

# Now we just generate the F-lines
echo_n "Generating F-lines... "
exec 4>>$conf_file

# The various log files are set up first--these are all that were defined
# in u2.10.10.pl15
if test x"$CONFIG_LOG_WHOX" = xy; then
    echo "F:LOG:WHO:FILE:$WPATH" >&4
fi
if test x"$CONFIG_LOG_GLINES" = xy; then
    echo "F:LOG:GLINE:FILE:$GPATH" >&4
fi
if test x"$CONFIG_LOG_USERS" = xy; then
    echo "F:LOG:USER:FILE:$FNAME_USERLOG" >&4
fi
if test x"$CONFIG_LOG_OPERS" = xy; then
    echo "F:LOG:OPER:FILE:$FNAME_OPERLOG" >&4
fi

# Now we traverse the entire feature table and compare values with their
# defaults
for feature in $features; do
    type=`getvar type_$feature`
    defval=`getvar def_$feature`
    value=`getvar FEAT_$feature`

    if test x"$defval" != x"$value"; then
	if test x"$type" = xB; then
	    # Must map booleans yet again; I prefer TRUE/FALSE
	    if test x"$value" = xy; then
		value=TRUE
	    else
		value=FALSE
	    fi
	fi

	# Write the F-line
	echo "F:$feature:$value" >&4
    fi
done
exec 4>&-
echo "done"

echo_n "Transition is complete."
if test ! -r $basedir/config.status; then
    echo_n "  You should now run ./configure."
fi

echo ""

if test x"$fline_conf" = xyes; then
    echo "Don't forget to add the F-lines to your ircd.conf.  They can be"
    echo "found in $conf_file."
else
    echo "Don't forget to verify the F-lines in your ircd.conf!"
fi
